home *** CD-ROM | disk | FTP | other *** search
- ;* ============================================================================ *
- ; Deluxe Music Construction Set II
- ; timer.asm -- CIA timer interrupt
- ; By Talin.
- ;* ============================================================================ */
-
- include "exec/types.i"
- include "exec/tasks.i"
- include "dos/dos.i"
- include "libraries/realtime.i"
-
- xdef _TimeServer
- xdef _CalcClockIncrement
-
- xref _tempo_rate
- xref _mclock_pos
- xref _mclock_accumulator
- xref _mclocks_per_column
- xref _pattern_mclocks
- xref _current_pattern_start
- xref _current_pattern_end
- xref _pattern_pos
- xref _column_pos
- xref _clock_pos
- xref _main_task
- xref _clock_state
-
- xref _SysBase
- xref _LVOSignal
-
- SECTION text,CODE
-
- _TimeServer
- move.l pmt_Method(a1),d0 ; d0 <-- method id
- cmp.l #PM_TICK,d0 ; is it a tick message?
- bne 10$
-
- ;---------- determine the number of ticks which have occured since
- ; the last time this hook was called.
-
- move.l pmt_Time(a1),d0 ; d0 <-- current clock time
- bmi 2$ ; DMCS doesn't deal with negative time...
- move.l _clock_pos,d1 ; d1 <-- time of last call
- sub.l d1,d0 ; d0 <-- time since last call
- bmi 2$ ; if clock went backwards, ignore...
- add.l d0,_clock_pos ; update accumulated time
-
- ;---------- Check to see if we're the Maestro
-
- * move.l pl_Source(a2),a0 ; a0 <-- Conductor
- * btst.b #CONDUCTB_METROSET,cdt_Flags+1(a0) ; if metronome already set
- * beq.s 1$
- * move.l cdt_Metronome(a0),d0 ; d0 <-- current metronome time
- * move.l d0,pl_MetricTime(a2) ; update playerinfo w/ time
- * bra.s 4$
-
- ; d0 now equals the number of ticks since the last time we updated _clock_pos.
- ; use this to do an extended precision multiply...
-
- move.l d0,d1 ; get copy of delta time
- swap d1 ; get upper half
- mulu.w _tempo_rate,d1 ; do extended precision math.
- swap d1 ; put extended part in upper
- clr.w d1 ; half of d1
-
- mulu.w _tempo_rate,d0 ; d0 <-- musical ticks since last
- add.l d1,d0 ; add extended precision part.
-
- ; d0 has now been converted to a delta-mclocks * 256
-
- add.l _mclock_accumulator,d0 ; d0 <-- total elapsed musical time
- move.l d0,_mclock_accumulator ; update tempo_accumulator
-
- ; d0 now contains to total elapsed mclocks.
-
- asr.l #8,d0 ; convert fixed-point to integer
-
- ;---------- since we're musically aware, update the "conducted" bit.
-
- ; move.l d0,cdt_Metronome(a0) ; update conductor metronome
- ; bset.b #CONDUCTB_METROSET,cdt_Flags+1(a0) ; set metronome flag
-
- cmp.l pl_MetricTime(a2),d0 ; see if they are the same
- beq.s 2$ ; no point in waking up if they are.
-
- 4$ move.l d0,pl_MetricTime(a2) ; see if they are the same
-
- ;---------- See if we overflowed into the next pattern
-
- 5$ cmp.l _current_pattern_end,d0 ; see if we're at the frame end
- blt.s 6$
-
- add.l #1,_pattern_pos ; add 1 to pattern position
- ; new start <-- old end
- move.l _current_pattern_end,_current_pattern_start
- ; new end += pattern size
- move.l _pattern_mclocks,d1
- add.l d1,_current_pattern_end
- bra.s 5$
-
- ;---------- calculate the column # within the pattern
-
- 6$ sub.l _current_pattern_start,d0 ; clocks in this pattern
- divu _mclocks_per_column,d0 ; get column #
-
- cmp.w _column_pos,d0 ; see if column # changed
- beq.s 2$ ; if so
-
- move.w d0,_column_pos ; then update column # and signal
-
- ;---------- get ExecBase into a6.
-
- move.l a6,-(sp)
- move.l _SysBase,a6
-
- ;---------- signal main task that a state change has occurred
-
- move.l _main_task,a1 ; address of player task
- move.l #SIGBREAKF_CTRL_F,d0 ; signal to send
- CALLLIB _LVOSignal ; wake up player task
-
- ;---------- restore a6 register
-
- move.l (sp)+,a6
-
- ;---------- just exit
-
- 2$ moveq #0,d0
- rts
-
- 10$ cmp.l #PM_STATE,d0 ; is it a state-change message?
- bne.s 20$
-
- ;---------- get ExecBase into a6.
-
- move.l a6,-(sp)
- move.l _SysBase,a6
-
- ;---------- signal main task that a state change has occurred
-
- move.l _main_task,a1 ; address of player task
- move.l #SIGBREAKF_CTRL_E,d0 ; signal to send
- CALLLIB _LVOSignal ; wake up player task
-
- ;---------- restore a6 register
-
- move.l (sp)+,a6
-
- ;---------- return from hook
-
- moveq #0,d0 ; end server chain???
- rts
-
- 20$
- ; cmp.l #PM_POSITION,d0 ; is it a special locate?
- ; bne.s 30$
- ;
- ;;---------- handle special locate message
- ;
- ; move.l pmt_Time(a1),_special_locate_time
- ;
- ; move.l a6,-(sp)
- ; move.l _SysBase,a6
- ;
- ;;---------- signal player task that a state change has occurred
- ;
- ; move.l _player_task,a1 ; address of player task
- ; move.l #SIGF_INTUITION,d0 ; signal to send
- ; Call Signal ; wake up player task
- ;
- ;;---------- restore a6 register
- ;
- ; move.l (sp)+,a6
-
- ;---------- return from hook
-
- 30$ moveq #0,d0 ; end server chain???
- rts
-
- _CalcClockIncrement ; (music delta)
- ; move.l 4(sp),d0 ; d0 <-- musical ticks
- ; lsl.l #8,d0 ; d0 <-- musical ticks * 256
- ; add.l _time_remainder,d0 ; plus remaining ticks
- ; divu.w _tempo_rate+2,d0 ; d0.w <-- real-time ticks
- ; swap.w d0 ; get remainder
- ; move.w d0,_time_remainder+2 ; put remainder into time remainder
- ; clr.w d0 ; clear lower half d0
- ; swap.w d0 ; d0.l <--real-time ticks
- ; rts
-
- end
-